package controller;

import javax.ejb.Stateless;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import utilities.googleMap.DistanceMatrix;
import utilities.json.JSONArray;
import utilities.json.JSONException;
import utilities.json.JSONObject;
import utilities.json.JSONReader;

/**
 * Metodi per interagire con Google Maps
 * @author lxn
 */
@Stateless
public class ControllerGMaps implements ControllerGMapsLocal {

    ControllerComuniLocal controllerComuni = lookupControllerComuniLocal();

    /**
     * Metodo che resituisce la lista di indirizzi riconosciuti da Google Maps compatibili con quello fornito in input
     * @param address indirizzo da cercare
     * @return la lista di indirizzi compatibili con quello in input
     */
    @Override
    public List<String> getAddresses(String address) {
        JSONArray results;
        JSONObject o, reply;
        List<String> l = new LinkedList<String>();
        String a = null;
        String url;
        
        try {
            a = URLEncoder.encode(address, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(ControllerGMaps.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        url = "https://maps.googleapis.com/maps/api/geocode/json?";
        url += "address=" + a + "&";
        url += "language=it-IT&";
        url += "sensor=false";
        
        try {
            reply = JSONReader.readJSONFromUrl(url);
            
            if (!reply.getString("status").equals("OK"))
                return l;
            
            results = reply.getJSONArray("results");
            
            for (int i = 0; i < results.length(); i++) {
                o = results.getJSONObject(i);
                l.add(o.getString("formatted_address"));
            }
        } catch (IOException ex) {
            Logger.getLogger(ControllerGMaps.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JSONException ex) {
            Logger.getLogger(ControllerGMaps.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return l;
    }
 
    /**
     * Metodo per verificare che un indirizzo sia riconosciuto univocamente da Google Maps
     * @param indirizzo indirizzo da cercare
     * @return true sse l'indirizzo può essere riconosciuto univocamente da Google Maps
     */
    @Override
    public boolean isUniqueAddress(String indirizzo){
        List<String> sugg = getAddresses(indirizzo);
        if (sugg.size() != 1) return false;
        String comune = DistanceMatrix.getLocality(sugg.get(0));
        String region = controllerComuni.getRegion(comune);
        return !"".equals(region);
    }
    
    private ControllerComuniLocal lookupControllerComuniLocal() {
        try {
            Context c = new InitialContext();
            return (ControllerComuniLocal) c.lookup("java:global/ShippingShareBisBis/ShippingShareBisBis-ejb/ControllerComuni!controller.ControllerComuniLocal");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }
    
}
